package com.neusoft.bizcore.web.websocket;

import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArraySet;

import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
@ConditionalOnClass(WebSocketMessageBrokerConfigurer.class)
@ConditionalOnProperty(name = "bizcore.web.websocket.enable", havingValue = "true")
public class SocketSessionRegistry {
    @Getter
    private final ConcurrentMap<String, Set<String>> sessions = new ConcurrentHashMap<>();
    private final Object lock = new Object();

    public SocketSessionRegistry() {
    }

    public Set<String> getSessionIds(String username) {
        final Set<String> set = this.sessions.get(username);
        return set != null ? set : Collections.emptySet();
    }

    public void registerSession(String username, String session) {
        if ((null == username) || (null == session)) {
            return;
        }
        SocketSessionRegistry.log.info("websocket session[{},{}] register.", username, session);
        synchronized (this.lock) {
            Set<String> set = this.sessions.get(username);
            if (set == null) {
                set = new CopyOnWriteArraySet<>();
                this.sessions.put(username, set);
            }
            set.add(session);
        }
    }

    public void unregisterSession(String username, String session) {
        if ((null == username) || (null == session)) {
            return;
        }
        SocketSessionRegistry.log.info("websocket session[{},{}] unregister.", username, session);
        synchronized (this.lock) {
            final Set<String> set = this.sessions.get(username);
            if ((set != null) && set.remove(session) && set.isEmpty()) {
                this.sessions.remove(username);
            }

        }
    }
}
